<?php
// +----------------------------------------------------------------------
// | 海豚PHP框架 [ DolphinPHP ]
// +----------------------------------------------------------------------
// | 版权所有 2016~2019 广东卓锐软件有限公司 [ http://www.zrthink.com ]
// +----------------------------------------------------------------------
// | 官方网站: http://dolphinphp.com
// +----------------------------------------------------------------------

namespace app\mill\model;

use think\Model;
use app\mill\model\Archives as ArchivesModel;
use app\mill\model\Finance as FinanceModel;
use app\admin\model\Config as ConfigModel;
use think\Db;

/**
 * 产品流水模型
 */
class Give extends Model
{
    // 设置当前模型对应的完整数据表名称
    protected $name = 'mill_order_archives_give';

    // 自动写入时间戳
    protected $autoWriteTimestamp = true;

    // 条形码每页显示数
    public static $_listRows = 500;

    //初始化处理
    public static function init(){
        static::__init();
    }

    //生产状态
    public static $give_status = [
        0 =>      '待生产',

    ];

    //生产状态
    public static $give_status_search = [
        0 =>      '待生产',
    ];

    //生产质检状态
    public static $quality_status = [
        -1 =>     '不合格',
        -2 =>     '报废',
        -3 =>     '已取消',
        0 =>      '待质检',
        1 =>      '合格',
        2 =>      '已返修',
    ];

    //打印状态
    public static $quality_repair = [
        0 =>      '待打印',
        1 =>      '待补件',
        2 =>      '已打印',
    ];

    //各部门权限
    //process:是否需要组装
    public static $role = [];

    //责任部门
    public static $quality_group = [];

    //各车间不需要的流水线配置
    public static $role_mill = [
        0   =>    [4],//组装
        1   =>    false,
    ];

    //配置可自动补扫的部门及需要补充到的状态
    public static $sup = [];

    //配置补扫部门ID
    public static $sup_group = '';
    //配置补扫账号
    public static $sup_uid = '';

    //流水线最后一个流程状态
    public static $last_give_status = 0;

    //初始化各状态
    protected static function __init(){

        //获取app所需的部门
        $group_role_list = Db::name('admin_user_group')->where([['app_page','<>',""],['is_give','=',1],['status','=',1]])->order('give_sort asc,sort asc')->column('*','id');
        //生产流水线流程
        $give_status_arr = Db::name('admin_user_group')->where([['app_page','<>',""],['is_give','=',1],['status','=',1],['give_sort','>',0]])->order('give_sort desc')->column('give_sort');
        self::$last_give_status = $give_status_arr[0];
        //获取各生产车间的生产权限
        $mill_role_list = Db::name('admin_user_mill')->where(['status'=>1])->order('id asc')->column('*','id');

        //获取app所需的部门
        foreach ($group_role_list as $grr){

            if(!empty($grr['give_sort'])){
                //责任部门
                self::$quality_group[$grr['give_sort']] = $grr['id'];
                //配置可自动补扫的部门及需要补充到的状态
                //self::$sup[$grr['id']] = $grr['give_sort'];
                //生产状态
                self::$give_status_search[$grr['give_sort']] = $grr['give_title'];
                self::$give_status[$grr['give_sort']] = static::$give_status_search[$grr['give_sort']];
                if($grr['app_page'] != 'address')self::$give_status[(-$grr['give_sort'])] = $grr['give_title'].'报废';
                //生产线流程
                $sort = $grr['give_sort'];
            }

            //补扫
            if($grr['app_page'] == 'speed' && empty($grr['give_sort'])){
                //配置补扫部门ID
                //self::$sup_group = $grr['id'];
                //配置补扫账号
                //self::$sup_uid = Db::name('admin_user')->where(['group'=>$grr['id']])->value('id');
                //生产线流程
                $sort = $give_status_arr[1];
            }

            //状态权限
            $status = [];
            if(!empty($sort)){
                for ($i=$sort;$i>0;$i--){
                    if(in_array($i,$give_status_arr))$status[] = $i;
                }
            }

            self::$role[$grr['id']] = [
                'name'          =>  $grr['give_title'],
                'quality'       =>  ($grr['app_page'] == 'quality'),//质检
                'color'         =>  !empty($grr['is_color']),
                'sub'           =>  !empty($grr['is_sub']),
                'status'        =>  $status,
            ];
        }
        ksort(self::$quality_group);
        ksort(self::$give_status);
        ksort(self::$give_status_search);

    }

    // 配置产品编号
    public static function giveSn($date=null,$batch=1,$sort=1){
        if(!$date)$date = time();
        else $date = count($date)==10?$date:strtotime($date);
        $date = date('ymd',$date);
        return $date.sprintf ("%03d", $batch)."-".sprintf ("%03d", $sort);
    }

    // 配置发货单号
    public static function addressSn($time=0,$sort=null){
        $config = new ConfigModel();

        if(!$time)$time = time();
        //$date = date('ym',$time);
        $date = date('Ymd',$time);
        //if(!$sort)$sort = $config->getConfig('mill_address_sn');

        return $date."-".sprintf ("%04d", $sort);
    }

    //验证部门API操作权限
    public static function role($user=[],$status=null,$give_sort=null){

        $give_status = abs($status);
        $give_status2 = $give_status > $user['give_sort'] ? $give_status : $user['give_sort'];

        if($give_status > $user['give_sort'] || !in_array($user['give_sort'],explode(',',$give_sort)))return "无[".self::$give_status[$give_status2]."]权限";
        elseif($status == $user['give_sort'])return '已出库';
        else return false;

    }

    //补一件产品
    public static function repair($id=null,$is_old_id=true){

        $where = ['id'=>$id];
        $give = Db::name('mill_order_archives_give')->where($where)->find();

        $quality_old_id = $give['id'];
        $quality_repair = 1;
        //是否录入补件产品信息
        if(empty($is_old_id)){
            $quality_old_id = '';
            $quality_repair = '';
        }

        //获取最后一件产品的计件数
        $counter = Db::name('mill_order_archives_give')
            ->where(['archives_id'=>$give['archives_id']])
            ->order('counter desc')
            ->value('counter');
        $counter++;//计件数+1
        //获取最后一件产品的序列
        $sort = Db::name('mill_order_archives_give')
            ->where(['give_date'=>$give['give_date'],'batch'=>$give['batch']])
            ->order('sort desc')
            ->value('sort');
        $sort++;//计件数+1
        $add = [
            'quality_old_id'        =>  $quality_old_id,
            'quality_repair'        =>  $quality_repair,
            'order_id'              =>  $give['order_id'],
            'order_pid'             =>  $give['order_pid'],
            'archives_id'           =>  $give['archives_id'],
            'archives_sn'           =>  $give['archives_sn'],
            'counter'               =>  $counter,
            'give_date'             =>  $give['give_date'],
            'batch'                 =>  $give['batch'],
            'sort'                  =>  $sort,
            'give_sn'               =>  self::giveSn($give['give_date'],$give['batch'],$sort),
        ];

        Db::name('mill_order_archives_give')->insert($add);
    }

    /**
     * 补足产品的补货状态
     * @param array $user 用户ID
     * @param int $do_status 补充到截止状态
     * @param array $give 产品信息
     * @return mixed
     */
    public static function giveToStatus($user = [],$do_status = 0,$give=[]){
        //$give['give_sort']：当前产品支持哪些扫码环节，根据情况进行补扫
        $give_sort = $give['give_sort'];
        $status = abs($give['status']);
        $log_list = [];//扫码记录
        //补状态
        if ($status < $do_status){
            $give_sort = ",0,{$give_sort},";
            $give_sort = explode(",{$status},",$give_sort);
            $give_sort = explode(',',trim($give_sort[1],','));
            foreach ($give_sort as $v){
                //补确认状态
                if(isset($give["status{$v}_sub"]))$update["status{$v}_sub"] = 2;
                if(isset($give["status{$v}_time"]))$update["status{$v}_time"] = time();

                $update["status_time"] = time();
                $update["status_uid"] = $user['uid'];
                $update["status"] = $do_status;

                //如果有过质检，则只更新当前的扫码记录，没有则更新补扫记录
                if($give['status'] >= 0 || $v == $do_status){
                    //扫码记录
                    $log = [
                        'status'            =>  $v,
                        'status_time'       =>  time(),
                        'status_uid'        =>  $user['uid'],
                        'mill_id'           =>  $user['mill_id'],
                        'group_id'          =>  empty($user['group_id'])?$user['group']:$user['group_id'],
                        'give_id'           =>  $give['id'],
                        'give_sn'           =>  $give['give_sn'],
                        'order_id'          =>  $give['order_id'],
                        'order_pid'         =>  $give['order_pid'],
                        'client_id'         =>  $give['client_id'],
                        'archives_id'       =>  $give['archives_id'],
                        'archives_sn'       =>  $give['archives_sn'],
                        'one_area'          =>  $give['one_area'],
                        'counter'           =>  $give['counter'],
                    ];
                    if($v != $do_status || empty($user['uid']))$log['is_bu'] = 1;//判断是不是补扫

                    //发货
                    if(!empty($give['is_address']) && $v == $do_status){
                        $update["car_id"] = $give['car_id'];
                        $update["address_sn"] = $give['address_sn'];

                        $log['car_id'] = $give['car_id'];
                        $log['address_sn'] = $give['address_sn'];
                        $log['address_date'] = $give['address_date'];
                        $log['address_time'] = $give['address_time'];
                        $log['address_status'] = $give['address_status'];

                    }

                    $log_list[] = $log;

                }

                if($v == $do_status)break;
            }
        }
        //回滚状态
        elseif ($status > $do_status){

            $give_sort = ",0,{$give_sort},";
            $give_sort = explode(",{$status},",$give_sort);
            $give_sort = explode(',',trim($give_sort[1],','));
            foreach ($give_sort as $v){
                //补之前的确认状态
                if(isset($give["status{$v}_sub"]))$update["status{$v}_sub"] = 0;
                if(isset($give["status{$v}_time"]))$update["status{$v}_time"] = 0;

                //如果有过质检，则只更新当前的扫码记录，没有则更新补扫记录
                if($v != $do_status){
                    //获取扫码记录
                    $log = Db::name('mill_order_archives_give_log')->where(['give_id'=>$give['id'],['status'=>$v]])->find();
                    if(!empty($log))$log['is_delete'] = 1;
                    $log_list[$log['id']] = $log;

                }
            }

            //获取最近一次的扫码记录
            $log = Db::name('mill_order_archives_give_log')->where(['give_id'=>$give['id'],['status'=>$do_status]])->find();
            $update["status_time"] = $log['status_time'];
            $update["status_uid"] = $log['status_uid'];
            $update["status"] = $log['status'];

            $update['address_sn'] = '';
            $update['address_date'] = '';
            $update['address_time'] = '';
            $update['address_status'] = '';
            $update['car_id'] = '';
        }
        //质检
        elseif ($give['status'] < 0){
            //补确认状态
            if(isset($give["status{$do_status}_sub"]))$update["status{$do_status}_sub"] = 2;
            $update["status{$do_status}_time"] = time();
            $update["status_time"] = time();
            $update["status_uid"] = $user['uid'];

            //扫码记录
            $log = [
                'status'            =>  $do_status,
                'status_time'       =>  time(),
                'status_uid'        =>  $user['uid'],
                'mill_id'           =>  $user['mill_id'],
                'group_id'          =>  empty($user['group_id'])?$user['group']:$user['group_id'],
                'give_id'           =>  $give['id'],
            ];

            $log_list[] = $log;
        }

        $update['log_list'] = $log_list;

        return $update;
    }
    //生成扫码记录
    public static function addGiveLog($log_list = []){
        if(!empty($log_list)){
            foreach ($log_list as $v){
                //判断是否需要删除扫码记录
                if(!empty($v['is_delete'])){
                    Db::name('mill_order_archives_give_log')->where(['id'=>$v['id']])->delete();
                    continue;
                }
                $where = [
                    'status'        =>  $v['status'],
                    'give_id'       =>  $v['give_id'],
                ];
                $log_id = Db::name('mill_order_archives_give_log')->where($where)->value('id');

                if(empty($log_id))Db::name('mill_order_archives_give_log')->insert($v);
                else Db::name('mill_order_archives_give_log')->where(['id'=>$log_id])->update($v);
            }
        }
    }
    //质检
    //-2:报废 -1:不合格 0:待质检 1:合格 2:已返修
    public static function quality($user=[],$post=[]){

        $where = [['give_sn','in',$post['give_sn']],['status','=',$post['give_status']]];
        $list = Db::name('mill_order_archives_give_log')->where($where)->select();

        if(!empty($list)){
            foreach ($list as $give){

                //质检状态 -2:报废 -1:不合格 0:待质检 1:合格 2:已返修
                //更新质检记录
                $add = $give;
                $add['status'] = -($give['status']);

                $quality = Db::name('mill_order_archives_give_quality')->where(['give_sn'=>$give['give_sn']])->find();

                $add['quality_errors'] = $post['quality_errors'];
                $add['quality_note'] = $post['quality_note'];
                $add['quality_uid'] = $user['uid'];
                $add['quality_time'] = time();
                if(empty($quality)){
                    unset($add['id']);
                    Db::name('mill_order_archives_give_quality')->insert($add);
                }
                else Db::name('mill_order_archives_give_quality')->where(['id'=>$quality['id']])->update($add);

                Db::name('mill_order_archives_give')->where(['id'=>$quality['give_id']])->update(['status'=>$add['status']]);

            }

            return true;

        }
        return false;

    }

    //根据用户ID或扫码状态获取对应值
    static function giveStatusOrUid($status_flow=null,$uid=null,$status=null){
        $data = '';
        if($uid){
            $give_status = explode("|{$uid}_",$status_flow);
            $give_status = array_filter($give_status);

            if(substr_count($status_flow,"|{$uid}_") == 1)$give_status = $give_status[0];
            else $give_status = end($give_status);

            if(isset($give_status)){
                $give_status = explode(',_',$give_status);
                $data = trim(end($give_status),'_');
            }

        }
        elseif ($status){
            $uid = explode("_{$status}|",$status_flow);
            if(isset($uid[1])){
                $uid = $uid[1];
                $uid = explode(',_',$uid);
                $data = trim($uid[0],'_');
            }
        }

        return $data;
    }

    // 分配发货单号
    public static function getAddressSn($time = 0){

        $config = new ConfigModel();

        //默认今天时间
        if(empty($time))$time = time();
        $update_time = true;
        //如果不是今天时间，则根据历史发货单号分配
        if(date('Ymd',$time) != date('Ymd'))$update_time = false;

        //分配今天的发货单
        if($update_time) {
            $sort = $config->getConfig('mill_address_sn');
            //发货单号计数器，如果不是今天的计数器，则重置并更新计数器
            if (strpos($sort, date('Ymd')) === false)ConfigModel::where('name', 'mill_address_sn')->update(['value' => date('Ymd') . "-0"]);
            $sort = $config->getConfig('mill_address_sn');
        }
        //分配历史发货单
        else {
            $status = self::$role[8]['status'][0];
            $where = [
                ["status{$status}_time",'between time',[date('Y-m-d',$time),date('Y-m-d 23:59:59',$time)]]
            ];
            $sort = Db::name('mill_order_archives_give')->where($where)->order('address_sn desc')->value('DISTINCT address_sn');
            if(empty($sort))$sort =  date('Ymd',$time) . "-0";
        }
        $sort = explode('-', $sort)[1];
        $sort ++;

        //分配发货单号
        $address_sn = self::addressSn($time,$sort);
        //更新发货单号
        if($update_time)ConfigModel::where('name', 'mill_address_sn')->update(['value' =>date('Ymd')."-".($sort)]);

        return $address_sn;
    }

    //定时任务，超过24小时未确认发货，则自动发货
    static function taskSubGiveAddress($address_sn='',$address_time=''){

        //24小时
        $time = (time()-86400);
        //发货状态
        $status = self::$last_give_status;
        //按批次分组
        $where = [
            ['address_sn','<>',''],
            ['status','=',$status],
            ['address_status','=',0],
        ];
        if(empty($address_sn))$where[] = ["status_time",'<=',$time];
        else $where[] = ['address_sn','=',$address_sn];

        $archives_ids = '';
        $give_list = Db::name('mill_order_archives_give')
            ->field("address_sn,order_id,order_pid,archives_sn,status_time,GROUP_CONCAT(id) as give_ids,GROUP_CONCAT(DISTINCT archives_id) as archives_ids")
            ->where($where)
            ->group('address_sn,order_id')
            ->select();
        $address_sn_s = Db::name('mill_order_archives_give')->where($where)->column('address_sn');
        if(!empty($address_sn_s))$address_sn_s = implode(',',$address_sn_s);

        if(!empty($give_list)){

            foreach ($give_list as $v){

                $time = strtotime(date('Y-m-d 23:59:59',$v["status_time"]));
                if(!empty($address_time))$time = $address_time;

                $archives_ids .= ",{$v['archives_ids']}";
                //分配发货单号
                if(strpos($address_sn_s,$v['address_sn']) !== false){
                    $address_sn = $v['address_sn'];
                    $address_sn_s = str_replace($v['address_sn'],"",$address_sn_s);
                }
                else $address_sn = self::getAddressSn($time);

                if(!empty($v['give_ids'])){
                    $save = [
                        'address_status'        =>  1,
                        'address_date'          =>  date('Y-m-d',$time),
                        'address_time'          =>  $time,
                        'address_sn'            =>  $address_sn,
                    ];

                    $give_where = [['id','in',$v['give_ids']]];

                    Db::name('mill_order_archives_give')->where($give_where)->update($save);
                    Db::name('mill_order_archives_give_log')->where([['give_id','in',$v['give_ids']]])->update($save);

                    //更新发货金额
                    FinanceModel::updateAddressPrice($v['order_id'],$address_sn);
                }

            }
            //exit;

            //检查更新产品主体状态
            if(!empty($archives_ids)){
                $archives_ids = explode(',',trim($archives_ids,','));
                foreach ($archives_ids as $archives_id){
                    ArchivesModel::checkStatus($archives_id,$status);
                }

            }

        }
    }

}
